package com.jerkin.spring.bean.definition;

import com.jerkin.model.User;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;

import java.util.Map;

import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;

/**
 * @version V1.0
 * @ClassName: AnnotationDefinitionDemo
 * @Description:注解生成definition的信息 其中有三种方式
 * 1 @Bean的方式
 * @author: huhongzhi
 * @date: 2020/10/9 23:12
 */
public class AnnotationDefinitionDemo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        applicationContext.register(AnnotationDefinitionDemo.class);
        // 通过 BeanDefinition 注册 API 实现
        // 1.命名 Bean 的注册方式
        registerUserBeanDefinition(applicationContext, "user");
        // 2. 非命名 Bean 的注册方法
        registerUserBeanDefinition(applicationContext);
        applicationContext.refresh();
//        User user = applicationContext.getBean(User.class);
//        System.out.println(user);
//        Map<String, User> map = applicationContext.getBeansOfType(User.class);
//        System.out.println(map);
//        //关闭上下文
        // 按照类型依赖查找
        System.out.println("Config 类型的所有 Beans" + applicationContext.getBeansOfType(Config.class));
        System.out.println("User 类型的所有 Beans" + applicationContext.getBeansOfType(User.class));
        System.out.println(applicationContext.getBean("user"));
        applicationContext.close();
    }

    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry, String beanName) {
        BeanDefinitionBuilder beanDefinitionBuilder = genericBeanDefinition(User.class);
        beanDefinitionBuilder
                .addPropertyValue("age", 18)
                .addPropertyValue("name", "jerkin");

        // 判断如果 beanName 参数存在时
        if (StringUtils.hasText(beanName)) {
            // 注册 BeanDefinition
            registry.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
        } else {
            // 非命名 Bean 注册方法
            BeanDefinitionReaderUtils.registerWithGeneratedName(beanDefinitionBuilder.getBeanDefinition(), registry);
        }
    }

    public static void registerUserBeanDefinition(BeanDefinitionRegistry registry) {
        registerUserBeanDefinition(registry, null);
    }


    public static class Config {
        @Bean(name = "user")
        public User generateUser() {
            User user = new User();
            user.setAge(18);
            user.setName("jerkin");
            return user;
        }
    }
}
